package org.akomantoso.core.io.util;

import java.io.IOException;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;

import org.akomantoso.core.data.AltHierarchyElement;
import org.akomantoso.core.data.ComponentRef;
import org.akomantoso.core.io.Input;
import org.akomantoso.core.io.InputConstants;
import org.akomantoso.core.io.util.group.ANcontainersGroup;
import org.akomantoso.core.io.util.group.BlockElementsGroup;
import org.akomantoso.core.io.util.group.ContainerElementsGroup;
import org.akomantoso.core.util.MapUtil;

public class AltHierarchyElementUtil {

	private AltHierarchyElementUtil() {
	}

	static final Map<String, Instantiator<AltHierarchyElement>> MAP;
	
	private static AltHierarchyElement instantiate(String elementName) {
		
		final Instantiator<? extends AltHierarchyElement> instatiator = MAP.get(elementName);
		if (instatiator == null) {
			throw new RuntimeException("Tag [" + elementName + "] not supported for AltHierarchyElement ?!?");
		}
		return instatiator.instantiate();
		
	}

	public static void read(Input in,List<AltHierarchyElement> elements,final String localName) throws IOException {
		
		AltHierarchyElement element = null;
		int eventType = in.getEventType();
		while(true) {
			if (eventType == InputConstants.START_ELEMENT) {
				elements.add(element = instantiate(in.getLocalName()));
				element.readExternal(in);
			}
			else if (in.getEventType() == InputConstants.END_ELEMENT && localName == in.getLocalName()) {
					return;
			}
			eventType = in.readNext();
		}
	}
	
	static {
		Map<String, Instantiator<AltHierarchyElement>> temp = new IdentityHashMap<String, Instantiator<AltHierarchyElement>>();
	
		MapUtil.copy(BlockElementsGroup.MAP, temp);
		MapUtil.copy(ContainerElementsGroup.MAP, temp);
		MapUtil.copy(ANcontainersGroup.MAP, temp);
			
		temp.put(ComponentRef.ELEMENT, new Instantiator<AltHierarchyElement>() {
			public AltHierarchyElement instantiate() {
				return new ComponentRef();
			}
		});
		
		MAP = temp;
	}
	
	
}